package com.benshou.bcss.common.tenant;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.benshou.bcss.common.j17common.NoThrowsAutoCloseable;
import com.benshou.bcss.common.j17common.annotation.Nullable;
import com.benshou.bcss.common.rest.RequestHeaderContext;

import java.util.List;

/**
 * 租户上下文
 *
 * @author <a href="mailto:liuzhenbang@benshou.com">Liu Zhenbang</a>
 */
public class TenantContext {

    /**
     * 线程本地变量：是否为公共环境（即无租户）
     */
    private static final ThreadLocal<Boolean> TL_PUBLIC = new TransmittableThreadLocal<>();

    /**
     * 短暂性地设置租户（资源关闭后恢复原状）
     *
     * @param tenantId 租户 Id
     * @return 租户资源
     */
    public static NoThrowsAutoCloseable transientTenant(Long tenantId) {
        var old = RequestHeaderContext.TENANT_ID.get();
        RequestHeaderContext.TENANT_ID.setSingleton(tenantId);
        return () -> RequestHeaderContext.TENANT_ID.set(old);
    }

    /**
     * 短暂性地设置公共环境（资源关闭后恢复原状）
     *
     * @return 公共环境资源
     */
    public static NoThrowsAutoCloseable transientPublic() {
        var old = TL_PUBLIC.get();
        TL_PUBLIC.set(true);
        return () -> TL_PUBLIC.set(old);
    }

    /**
     * 设置租户 Id
     *
     * @param tenantId 租户 Id
     */
    public static void setTenantId(Long tenantId) {
        RequestHeaderContext.TENANT_ID.set(tenantId == null ? null : List.of(tenantId));
    }

    /**
     * @return 租户 Id
     */
    @Nullable
    public static Long getTenantId() {
        return RequestHeaderContext.TENANT_ID.getFirst();
    }

    /**
     * 移除租户 Id
     */
    public static void removeTenantId() {
        RequestHeaderContext.TENANT_ID.remove();
    }

    /**
     * 设置为公共环境
     */
    public static void setPublic() {
        TL_PUBLIC.set(true);
    }

    /**
     * @return 是否为公共环境
     */
    public static boolean isPublic() {
        return Boolean.TRUE.equals(TL_PUBLIC.get());
    }

    /**
     * 移除公共环境（即设置为租户环境）
     */
    public static void removePublic() {
        TL_PUBLIC.remove();
    }
}
